/* 路由鉴权:鉴权-项目中路由能不能被访问的权限设置(某一个路由什么条件下可以访问、什么条件下不可以访问) */
import router from '@/router'
//引入项目的标题|logo配置
import setting from './setting'
//引入进度条插件
//@ts-expect-error否则报红
import nprogress from 'nprogress'
//引入进度条样式
import 'nprogress/nprogress.css'
//不显示加载动画(右面转圈的小球)
nprogress.configure({ showSpinner: false })
//获取用户相关的小仓库内部的token,去判断用户是否登录成功
import useUserStore from './store/modules/user'
import pinia from './store'
// 外部JS文件使用仓库的时候， 实例化仓库一定要放在函数中（前置守卫），否则数据持久化会失效； 后面做按钮权限也是一样。
const userStore = useUserStore(pinia)
/*
   全局守卫:项目中任意路由切换都会触发的钩子
   第一个问题:任意路由切换时实现进度条显示 --- nprogress插件
   第二个问题:路由鉴权(路由组件访问权限的设置)
      全部路由组件:登录|404|任意路由|数据大屏|首页|权限管理(三个子路由)|商品管理(四个子路由)
      用户未登录:可以访问login,其余六个路由不能访问(会跳转到login)
      用户登录成功:不可以访问login(会跳转到首页),其余的路由可以访问
 */
//全局前置守卫
router.beforeEach(async (to: any, from: any, next: any) => {
  //路由切换时动态设置文档(网页)的标题
  document.title = `${setting.title} - ${to.meta.title}`
  //to:将要访问那个路由对象 from:从来个路由对象而来 next:路由的放行函数
  nprogress.start()
  //获取token,去判断用户登录还是未登录
  const token = userStore.token
  //获取用户名字
  const username = userStore.username
  if (token) {
    //用户已登录
    if (to.path == '/login') {
      // 登录成功访问login,不能访问,指向首页
      next({ path: '/' })
    } else {
      //登录成功访问其余六个路由(登录排除)
      if (username) {
        //有用户信息->放行
        next()
      } else {
        //如果没有用户信息,在守卫这里发请求获取到了用户信息再放行
        try {
          //获取用户信息, async userInfo(): Promise<string>, 所以要await
          await userStore.userInfo()
          //放行 -> 如果刷新的时候是异步路由,有可能获取到了用户信息, 但异步路由还没有动态加载完毕,这样就出现空白的效果
          next({ ...to }) // 这里必须要加...to(对象展开), 保证刷新的时候异步路由已经加载完毕, 再进行跳转
        } catch (error) {
          //获取不到用户信息: ①token过期 ②用户手动修改了本地存储的token
          await userStore.userLogout() //退出登录->用户相关的数据清空。如果不加await，由于userLogout()是异步的，则不会跳转到登录页。
          next({ path: '/login', query: { redirect: to.path } })
        }
      }
    }
  } else {
    //用户未登录
    if (to.path == '/login') {
      next()
    } else {
      // to.path代表想去而没有去成的路由
      next({ path: '/login', query: { redirect: to.path } })
    }
  }
})
//全局后置守卫
/*
这里刘小斌修改过,为了eslint
router.afterEach((to: any, from: any) => {
  nprogress.done()
})
*/
router.afterEach(() => {
  nprogress.done()
})
